package com.maimao.kill.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.maimao.api.kill.KillApplyApi;
import com.maimao.core.model.auth.AuthUser;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.model.resp.Result;
import com.maimao.core.utils.DateUtils;
import com.maimao.kill.client.ShopClient;
import com.maimao.kill.controller.base.BaseController;
import com.maimao.kill.mapper.ActivityMapper;
import com.maimao.kill.mapper.ScheduleMapper;
import com.maimao.kill.service.KillApplyService;
import com.maimao.model.kill.Activity;
import com.maimao.model.kill.ApplySku;
import com.maimao.model.kill.KillApply;
import com.maimao.model.kill.Schedule;
import com.maimao.model.kill.enums.CheckTypeEnum;
import com.maimao.model.kill.enums.KillApplyStatusEnum;
import com.maimao.model.kill.input.ActivityScheduleIdInput;
import com.maimao.model.user.Shop;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import static com.maimao.core.constant.Constants.ZERO;

/**
 * @author MaoLin Wang
 * @date 2021/4/8 3:20 下午
 */
@RestController
@RequestMapping("/kill/killApply")
public class KillApplyController extends BaseController implements KillApplyApi {

    public static final int APPLY_HOUR_LIMIT = 15;
    @Autowired
    private ShopClient shopClient;

    @Autowired
    private KillApplyService killApplyService;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private ScheduleMapper scheduleMapper;

    /**
     * 后台审核查询或商家自己查询申请记录
     *
     * @param killApply 查询条件
     */
    @Override
    @PostMapping("/query")
    public Result<?> query(@RequestBody KillApply killApply,
                                               @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                                               @RequestParam(value = "size", required = false, defaultValue = "20") Integer size) {
        AuthUser authUser = checkAndGetAuthUser();
        if (killApply.getShop() != null && killApply.getShop()) {
            killApply.setShopId(authUser.getShopId());
        }
        return Result.okData(killApplyService.query(killApply, page, size));
    }

    /**
     * 商家申请参与秒杀(可一次申请多个商品)
     *
     * @param killApplyList 参与秒杀的信息
     * @return
     */
    @Override
    @PostMapping("/apply")
    public Result apply(@RequestBody @Validated List<KillApply> killApplyList) {
        if (killApplyList == null) {
            return Result.notValid("请选择商品");
        }
        if (killApplyList.size() > 5) {
            return Result.notValid("一次最多只允许报名5类商品");
        }
        AuthUser authUser = checkAndGetAuthUser();
        LocalDateTime now = DateUtils.now();
        for (KillApply killApply : killApplyList) {
            Result x = checkApplyInput(authUser, now, killApply);
            if (x != null) return x;
        }

        List<ApplySku> appliedSku = killApplyService.apply(killApplyList);
        if (ObjectUtil.isNotEmpty(appliedSku)) {
            return Result.notValid("您选择的商品中存在当前活动排期已经申请过的sku记录，请重新选则");
        }
        return Result.ok("报名成功，请注意查看审核信息");
    }

    /**
     * 人工审核 入参：id、status 【reply】
     *
     * @param killApply
     * @return
     */
    @PostMapping("/check-manual")
    @Override
    public Result<?> checkManul(@RequestBody KillApply killApply) {
        if (killApply == null || killApply.getId() == null || killApply.getStatus() == null) {
            return Result.notValid();
        }
        if (killApply.getStatus().equals(KillApplyStatusEnum.FAIL.getCode()) && StrUtil.isEmpty(killApply.getReply())) {
            return Result.notValid("请填写驳回原因");
        }
        killApply.setCheckType(CheckTypeEnum.MANUAL.getStatus());
        killApplyService.checkApply(Lists.newArrayList(killApply));
        return Result.ok("审核成功");
    }

    @Override
    @PostMapping("/cancel")
    public Result cancel(@RequestParam("id") Long id) {
        if (id == null || id <= 0) {
            return Result.notValid();
        }
        return killApplyService.back(id);
    }


    /**
     * 根据活动id和排期id查询已报名(审核通过或未审核的)的skuId列表
     *
     * @param input 二元组 field1：活动id field2：排期id
     */
    @Override
    @PostMapping("/querySkuIdsByAcSch")
    public Result<?> querySkuIdsByAcSch(@RequestBody ActivityScheduleIdInput input) {
        if (input == null || input.getActivityId() == null || input.getScheduleId() == null) {
            return Result.notValid();
        }
        Integer activityId = input.getActivityId();
        Long scheduleId = input.getScheduleId();

        List<Long> skuIds = killApplyService.querySkuIdsByAcSch(activityId, scheduleId);
        return Result.okData(skuIds);
    }

    private Result checkApplyInput(AuthUser authUser, LocalDateTime now, KillApply killApply) {
        Activity activity = activityMapper.selectById(killApply.getActivityId());
        if (activity == null || activity.getStatus().equals(ZERO)) {
            return Result.notValid("活动已停止");
        }
        Schedule schedule = scheduleMapper.selectById(killApply.getScheduleId());
        if (schedule == null || schedule.getEnabled().equals(ZERO)) {
            return Result.notValid("排期已关闭");
        }
        LocalDate startTime = schedule.getStartTime().toLocalDate();
        if (startTime.compareTo(now.toLocalDate()) < ZERO) {
            //排期在当日或之前
            return Result.notValid("排期已开始或已过了报名时间");
        }
        //只能报名次日以后的排期，且次日的排期必须在当日15:00之前完成报名，因为后面需要时间审核和预热秒杀商品
       /* if ((startTime.plusDays(-1).compareTo(now.toLocalDate()) <= 0) && now.getHour() >= APPLY_HOUR_LIMIT) {
            return Result.notValid("次日排期只能在15:00之前进行报名");
        }*/
        if (killApply.getShopId() == null || StrUtil.isEmpty(killApply.getShopName())) {
            if (authUser.getShopId() == null) {
                return Result.notValid("尚未开通店铺");
            }
            killApply.setShopId(authUser.getShopId());
            Result<Shop> shopResult = shopClient.queryByIdIn(authUser.getShopId());
            if (shopResult != null && shopResult.getData() != null) {
                killApply.setShopName(shopResult.getData().getName());
            }
        }
        killApply.setCreateTime(DateUtils.now());
        killApply.setCancel(ZERO);
        killApply.setStatus(KillApplyStatusEnum.UN_CHECK.getCode());
        return null;
    }
}
